﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Dycox.Workflows
{
    public abstract class ProcessOperation : TransitionOperation
    {
        protected override void PerformCore(TransitionOperationArguments args)
        {
            var cpoc = args.Context.UserState as ICrossProcessOperationContract;
            WFProcess process;

            if (cpoc != null)
            {
                if (!SupportsCrossProcessOperation)
                    throw new NotSupportedException(SR.GetString("corss_process_operation_not_supported"));
                process = (WFProcess)args.Context.DataProvider.GetComponent(new ComponentIdentifier(cpoc.ProcessId), true);
            }
            else
                process = args.Context.Process;

            PerformCore(process, args);
        }

        protected abstract void PerformCore(WFProcess process, TransitionOperationArguments args);

        protected virtual bool SupportsCrossProcessOperation
        {
            get { return true; }
        }
    }

    public sealed class SuspendProcessOperation : ProcessOperation
    {
        public SuspendProcessOperation(ProcessSuspendingReasons reason)
        {
            if (reason == ProcessSuspendingReasons.None)
                throw new ArgumentException(SR.GetString("reason_is_required"));

            _reason = reason;
        }

        private ProcessSuspendingReasons _reason;

        public ProcessSuspendingReasons Reason
        {
            get { return _reason; }
        }

        protected override void PerformCore(WFProcess process, TransitionOperationArguments args)
        {

            var control = args.Context.Workflow.Control;
            
            if (!control.IsProcessSuspended(process, _reason))
                control.SuspendProcess(process, _reason);
                
        }

        public override TransitionTypes SupportedTransitionTypes
        {
            get { return TransitionTypes.ExitStage | TransitionTypes.NoMoreStep; }
        }
    }

    public sealed class ResumeProcessOperation : ProcessOperation
    {
        public ResumeProcessOperation(ProcessSuspendingReasons reason)
        {
            _reason = reason;
        }

        private ProcessSuspendingReasons _reason;

        public ProcessSuspendingReasons Reason
        {
            get { return _reason; }
        }

        protected override void PerformCore(WFProcess process, TransitionOperationArguments args)
        {
            var control = args.Context.Workflow.Control;

            if (control.IsProcessSuspended(process, _reason))
                control.ResumeProcess(process, _reason);
        }

        public override TransitionTypes SupportedTransitionTypes
        {
            get { return TransitionTypes.ExitStage | TransitionTypes.NoMoreStep; }
        }
    }

}
